package cn.kgc.tangcco.service.impl;

import cn.kgc.tangcco.service.IdiomService;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestOperations;

import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * @author 李昊哲
 * @Description
 * @create 2021/1/27 18:50
 */
@Service
public class IdiomServiceImpl implements IdiomService {

    private final DiscoveryClient discoveryClient;

    // Ribben 负载均衡器
    private final LoadBalancerClient loadBalancerClient;

    private final RestOperations restTemplate;

    public IdiomServiceImpl(DiscoveryClient discoveryClient, LoadBalancerClient loadBalancerClient, RestOperations restTemplate) {
        this.discoveryClient = discoveryClient;
        this.loadBalancerClient = loadBalancerClient;
        this.restTemplate = restTemplate;
    }


    @Override
    public String finAllByDiscoveryClient(Integer page, Integer limit) {
        List<String> services = discoveryClient.getServices();
        if (CollectionUtils.isEmpty(services)) {
            // 未获取服务列表 则返回null
            return null;
        }
        // 根据服务名称获取服务
        List<ServiceInstance> instances = discoveryClient.getInstances("idiom-provider");
        if (CollectionUtils.isEmpty(instances)) {
            // 未获取服务 则返回null
            return null;
        }


        ServiceInstance serviceInstance = instances.get(ThreadLocalRandom.current().nextInt(instances.size()));
        StringBuffer sb = new StringBuffer();
        sb.append("http://");
        sb.append(serviceInstance.getHost());
        sb.append(":");
        sb.append(serviceInstance.getPort());
        sb.append("/idiom/page");
        String url = sb.toString();
        HttpHeaders headers = new HttpHeaders();
        //  请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //  封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        MultiValueMap<String, Integer> params = new LinkedMultiValueMap<>();
        //  也支持中文
        params.add("page", page);
        params.add("limit", limit);
        HttpEntity<MultiValueMap<String, Integer>> requestEntity = new HttpEntity<>(params, headers);
        //  执行HTTP请求
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, new ParameterizedTypeReference<>() {
        });
        //  输出结果
        return response.getBody();
    }

    @Override
    public String finAllByLoadBalancerClient(Integer page, Integer limit) {
        // 根据服务名称获取服务
        ServiceInstance serviceInstance = loadBalancerClient.choose("idiom-provider");
        if (serviceInstance == null) {
            return null;
        }
        StringBuffer sb = new StringBuffer();
        sb.append("http://");
        sb.append(serviceInstance.getHost());
        sb.append(":");
        sb.append(serviceInstance.getPort());
        sb.append("/idiom/page");
        String url = sb.toString();
        HttpHeaders headers = new HttpHeaders();
        //  请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //  封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        MultiValueMap<String, Integer> params = new LinkedMultiValueMap<>();
        //  也支持中文
        params.add("page", page);
        params.add("limit", limit);
        HttpEntity<MultiValueMap<String, Integer>> requestEntity = new HttpEntity<>(params, headers);
        //  执行HTTP请求
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, new ParameterizedTypeReference<>() {
        });
        //  输出结果
        return response.getBody();
    }

    @Override
    public String finAllByLoadBalancerClientAnnotation(Integer page, Integer limit) {
        String url = "http://idiom-provider/idiom/page";
        HttpHeaders headers = new HttpHeaders();
        //  请勿轻易改变此提交方式，大部分的情况下，提交方式都是表单提交
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        //  封装参数，千万不要替换为Map与HashMap，否则参数无法传递
        MultiValueMap<String, Integer> params = new LinkedMultiValueMap<>();
        //  也支持中文
        params.add("page", page);
        params.add("limit", limit);
        HttpEntity<MultiValueMap<String, Integer>> requestEntity = new HttpEntity<>(params, headers);
        //  执行HTTP请求
        ResponseEntity<String> response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, new ParameterizedTypeReference<>() {
        });
        //  输出结果
        return response.getBody();
    }
}
